{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. LeNet-5卷积神经网络"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假如对多神经元的模型97.37%的准确率还不满意\n",
    "可以使用卷积神经网络模型LeNet-5来解决问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-1-3c98a8d00530>:7: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ../data/train-images-idx3-ubyte.gz\n",
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ../data/train-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n",
      "Extracting ../data/t10k-images-idx3-ubyte.gz\n",
      "Extracting ../data/t10k-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "训练集数量： 55000\n",
      "验证集数量： 5000\n",
      "测试集数量： 10000\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# 载入数据集\n",
    "mnist = input_data.read_data_sets(\"../data/\", one_hot=True)\n",
    "\n",
    "# 显示数据集数量\n",
    "print(\"训练集数量：\", mnist.train.num_examples)\n",
    "print(\"验证集数量：\", mnist.validation.num_examples)\n",
    "print(\"测试集数量：\", mnist.test.num_examples)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 数据读取"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "利用网上的 MNIST 数据集(http://yann.lecun.com/exdb/mnist/)获取数据集压缩文件（切勿解压）：\n",
    "\n",
    "train-images-idx3-ubyte.gz --- 6万张28x28大小的训练数字图像\n",
    "\n",
    "train-labels-idx1-ubyte.gz --- 6万张训练图像的数字标记\n",
    "\n",
    "t10k-images-idx3-ubyte.gz  --- 1万张28x28大小的测试数字图像\n",
    "\n",
    "t10k-labels-idx1-ubyte.gz  --- 1万张测试图像的数字标记"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练图像大小： (55000, 784)\n",
      "训练标签大小： (55000, 10)\n"
     ]
    }
   ],
   "source": [
    "# 显示数据集大小\n",
    "print(\"训练图像大小：\", mnist.train.images.shape)\n",
    "print(\"训练标签大小：\", mnist.train.labels.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n"
     ]
    }
   ],
   "source": [
    "# 可视化图像\n",
    "def plot_image(image):\n",
    "    plt.imshow(image.reshape(28, 28), cmap='binary')\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "# 可视化第二张训练图像\n",
    "plot_image(mnist.train.images[2])\n",
    "\n",
    "# 可视化第二张图像的标签\n",
    "print(mnist.train.labels[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 构建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From c:\\users\\dell\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\tensorflow\\python\\framework\\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "# 定义训练数据的占位符， x是784个像素点的特征值， y是10分类的标签值\n",
    "x = tf.placeholder(tf.float32, [None, 784], name=\"X\")\n",
    "y = tf.placeholder(tf.float32, [None, 10], name=\"Y\")\n",
    "\n",
    "# 为了使用卷积层，需把x变成一个4d向量，其第2、第3维对应图片的宽、高，最后一维代表图片的颜色通道数\n",
    "x_image = tf.reshape(x, [-1, 28, 28, 1])\n",
    "\n",
    "\n",
    "# 权重W 初始化 从标准差0.1的截断正态分布中输出随机值\n",
    "def weight_variable(shape):\n",
    "    initial = tf.truncated_normal(shape, stddev=0.1)\n",
    "    return tf.Variable(initial)\n",
    "\n",
    "\n",
    "# 权重b 初始化 0.1\n",
    "def bias_variable(shape):\n",
    "    initial = tf.constant(0.1, shape=shape)\n",
    "    return tf.Variable(initial)\n",
    "\n",
    "\n",
    "# 定义1步长的 valid卷积\n",
    "def conv2d(x, W):\n",
    "    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='VALID')\n",
    "\n",
    "\n",
    "# 定义步长为2 大小2x2的 max pooling\n",
    "def max_pool_2x2(x):\n",
    "    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')\n",
    "\n",
    "\n",
    "# 第一层卷积 每个5x5的patch中算出6个特征\n",
    "W_conv1 = weight_variable([5, 5, 1, 6])\n",
    "b_conv1 = bias_variable([6])\n",
    "\n",
    "# 第一层relu激活\n",
    "h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)\n",
    "\n",
    "# 第一层池化\n",
    "h_pool1 = max_pool_2x2(h_conv1)\n",
    "\n",
    "# 第二层卷积 每个5x5的patch中算出16个特征\n",
    "W_conv2 = weight_variable([5, 5, 6, 16])\n",
    "b_conv2 = bias_variable([16])\n",
    "\n",
    "# 第二层relu激活\n",
    "h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)\n",
    "\n",
    "# 第二层池化\n",
    "h_pool2 = max_pool_2x2(h_conv2)\n",
    "\n",
    "# 第三层全连接\n",
    "W_fc1 = weight_variable([4 * 4 * 16, 120])\n",
    "b_fc1 = bias_variable([120])\n",
    "h_pool2_flat = tf.reshape(h_pool2, [-1, 4 * 4 * 16])  # 重新展开\n",
    "h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)\n",
    "\n",
    "# 第四层全连接\n",
    "W_fc2 = weight_variable([120, 84])\n",
    "b_fc2 = bias_variable([84])\n",
    "h_fc2 = tf.nn.relu(tf.matmul(h_fc1, W_fc2) + b_fc2)\n",
    "\n",
    "# 输出层 softmax层\n",
    "W_fc3 = weight_variable([84, 10])\n",
    "b_fc3 = bias_variable([10])\n",
    "forward = tf.matmul(h_fc2, W_fc3) + b_fc3\n",
    "pred = tf.nn.softmax(forward)\n",
    "\n",
    "train_epochs = 20  # 迭代次数\n",
    "learning_rate = 1e-3  # 学习率\n",
    "\n",
    "# 定义损失函数\n",
    "with tf.name_scope(\"LossFunction\"):\n",
    "    loss_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=forward, labels=y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch 01 Loss= 0.108200222 Accuracy= 0.9696\n",
      "Train Epoch 02 Loss= 0.066758297 Accuracy= 0.9822\n",
      "Train Epoch 03 Loss= 0.064959630 Accuracy= 0.9822\n",
      "Train Epoch 04 Loss= 0.049632501 Accuracy= 0.9852\n",
      "Train Epoch 05 Loss= 0.041107506 Accuracy= 0.9886\n",
      "Train Epoch 06 Loss= 0.041755408 Accuracy= 0.9884\n",
      "Train Epoch 07 Loss= 0.041898545 Accuracy= 0.9898\n",
      "Train Epoch 08 Loss= 0.036958639 Accuracy= 0.9908\n",
      "Train Epoch 09 Loss= 0.039780248 Accuracy= 0.9906\n",
      "Train Epoch 10 Loss= 0.057369702 Accuracy= 0.9822\n",
      "Train Epoch 11 Loss= 0.041729357 Accuracy= 0.9906\n",
      "Train Epoch 12 Loss= 0.044323169 Accuracy= 0.9898\n",
      "Train Epoch 13 Loss= 0.039810352 Accuracy= 0.9906\n",
      "Train Epoch 14 Loss= 0.045707256 Accuracy= 0.9878\n",
      "Train Epoch 15 Loss= 0.036656860 Accuracy= 0.9902\n",
      "Train Epoch 16 Loss= 0.041974217 Accuracy= 0.9906\n",
      "Train Epoch 17 Loss= 0.046835992 Accuracy= 0.9906\n",
      "Train Epoch 18 Loss= 0.035773896 Accuracy= 0.9910\n",
      "Train Epoch 19 Loss= 0.041715056 Accuracy= 0.9892\n",
      "Train Epoch 20 Loss= 0.041373160 Accuracy= 0.9912\n"
     ]
    }
   ],
   "source": [
    "# Adam优化器 设置学习率和优化目标损失最小化\n",
    "optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss_function)\n",
    "\n",
    "# 定义预测类别匹配情况\n",
    "correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))\n",
    "\n",
    "# 定义准确率，将布尔值转化成浮点数，再求平均值\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_prediction, \"float\"))\n",
    "\n",
    "# 每个批次的大小，每次放入的大小，每次放入 100张图片 以矩阵的方式\n",
    "batch_size = 100\n",
    "\n",
    "# 计算一共有多少个批次，数量整除大小训练出有多少批次\n",
    "n_batch = mnist.train.num_examples // batch_size\n",
    "\n",
    "sess = tf.Session()  # 建立会话\n",
    "init = tf.global_variables_initializer()  # 变量初始化\n",
    "sess.run(init)\n",
    "\n",
    "for epoch in range(train_epochs):\n",
    "    for batch in range(n_batch):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        sess.run(optimizer, feed_dict={x: xs, y: ys})\n",
    "        # 批次训练完成之后，使用验证数据计算误差与准确率\n",
    "    loss, acc = sess.run([loss_function, accuracy],\n",
    "                         feed_dict={x: mnist.validation.images,\n",
    "                                    y: mnist.validation.labels})\n",
    "    # 显示训练信息\n",
    "    print(\"Train Epoch\", '%02d' % (epoch + 1), \"Loss=\", '{:.9f}'.format(loss), \"Accuracy=\",\n",
    "          \"{:.4f}\".format(acc))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 评估模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test Accuracy =  0.9902\n",
      "Validation Accuracy =  0.9912\n"
     ]
    }
   ],
   "source": [
    "# 测试集上评估模型预测的准确率\n",
    "accu_test = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})\n",
    "print(\"Test Accuracy = \", accu_test)\n",
    "\n",
    "# 验证集上评估模型预测的准确率\n",
    "accu_validation = sess.run(accuracy, feed_dict={x: mnist.validation.images, y: mnist.validation.labels})\n",
    "print(\"Validation Accuracy = \", accu_validation)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. 模型预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4 7 1 2 4 0 2 7 4 3]\n"
     ]
    }
   ],
   "source": [
    "# 转换pred预测结果独热编码格式为数字0-9\n",
    "prediction_result = sess.run(tf.argmax(pred, 1), feed_dict={x: mnist.test.images})\n",
    "\n",
    "# # 查看第300-309张测试图片的预测结果\n",
    "print(prediction_result[300:310])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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pc2dO1fHv/71r620zZs3R4zd/Tp27Kjj+vXrJ1dYimnjxo06Puecc6y0Cy+8UMdvvvmmlValSpWEz/XVV19Z288++6yOx4wZk3B+mcY7REREROQ9NoiIiIjIe151mX3++efW9k8//aRjdpmlxpEjR3T82WefWWnu0gbx+u6773T88MMPR4wBe0rpW2+9ZaXVq1dPxyVKlChUOSh9Dhw4kOki5LSRI0da26+88oqOV61aZaWZ79sOHTpYaeYK43Xr1tXx+++/b+330EMP6Xj48OFW2v333x9vsSkOs2bNippmDlt4/vnnrbQBAwYkfW633osb3iEiIiIi77FBRERERN5jg4iIiIi8l/NjiPbv36/jPn36RN2vffv26ShOzitfvryOBw4caKX97W9/07E5PT9VzCmgDRo0sNI++OADHV900UUpPzel1rZt2zJdhGJv9+7d1vYVV1yhY/eRC926ddOxueQBcOIU+sKYMmWKjs2p2QDw/fff69gdX1SmTJmkz02ptWnTpqhpO3fuTGNJUo93iIiIiMh7bBARERGR93K+y+wf//iHjmPdhu/SpUs6iuMVd1q8ect+7dq1VtrMmTN1vHDhQivt559/TrosZncdu8yy329/+9tMF6HYGzx4sLW9YcMGHd9yyy1W2tixY3VcunTplJela9euEWPA/lz4wx/+YKWZ3Wtly5ZNeblyUc2aNVO6n+vw4cOFOq444B0iIiIi8h4bREREROQ9NoiIiIjIezkxhkgpZW1PmDBBxw888EBcefDRHUXv0ksvjRgDwN13363jvn37WmnRlqJ3xxaZj/hwmdOMv/76ayutsH3plLhjx45FjCn1zKnuANC/f38djxgxIt3Fier111/X8bnnnmulrV69WsfNmjVLW5mKM/fzLRpzSZpEmEuamOPScgHvEBEREZH32CAiIiIi7+VEl5l72+6OO+6IuJ/5NHTAXtmYsoe5VEKk7Xzu9PzLLrssap5mXZsr4wLsMksnc7kFt/5Mc+fO1XG/fv2KtEy5ynwSPQBUrlw5QyWJrUKFCjru0aOHlWZ2p7HLLLXatGlTqOPWrFkTNa1KlSqFLU5W4B0iIiIi8h4bREREROQ9NoiIiIjIe8V2DNFnn32m4yZNmkTdb/369TrmIxuIMqtu3bo6bty4sY7N9zMQe5wCxeexxx6ztmONscsW7hIqVHR2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v9za3r59u47btGljpbVo0SItZaLUMLuQXTVq1EhjSXJTu3btrG1zBfFDhw5FPe7GG2+0tqOtMr1582Zru0uXLnGVq3Tp0tZ2Lq+KnGldu3a1tqdPn67j5557Tsfu6vJPPfVU0RYsg3iHiIiIiLzHBhERERF5L6u7zIhcd999t44//fRTK82cWfb73//eSnNvxVNm/PLLLxHj9evXW/uZM15cderU0fHhw4etNPN3gLOSoqtZs6a1bc7mitVl5nZlXnjhhTqeOnWqjt944w1rv23btunYnQFq6t+/v7Xds2fPqPtSar3yyis6Pv3003X85JNPWvt9+eWXOu7Tp4+Vds011xRR6dKDd4iIiIjIe2wQERERkffYICIiIiLvZXwMkftU8lxmjndwr3vw4MHpLk7WcscwmFNAn376aR2fdJLdnv/f//1fHbdv376ISkcu88n0gD0t98cff7TS1q1bp2P3KfbxMp9wX7lyZSvt5ptv1vHo0aMLlb+Ppk2bpuNrr73WStu3b5+OzXFfALB06VIdm2O7XLE+5ytWrKjjDh06FFxYKnLme8ddMsF8j/Xq1ctKu+OOO3R83333WWlnnHFGCktYNHiHiIiIiLzHBhERERF5L+NdZuYUzFjTMXOBeRvSvdZy5cqluzhZa8SIEdb2I488omPz5zZ06FBrP3aTpc/OnTt13KxZMytt7969RXpus8ts3LhxVtpvfvObIj13rjKXqXCnUo8aNSql53I/+8yulebNm6f0XJS8iy66yNpevXq1jnv37m2l/f3vf9fxs88+a6WZ3bLukwSyBe8QERERkffYICIiIiLvsUFERERE3sv4GCLzifZ79uyx0mbPnq1jc6pfcWFOSQWAHTt26NidLtyvX7+0lClb3XPPPTqePHly1P3MablDhgwp0jJRdGXLltXx7bffbqWZ79tYDh48qOMtW7ZE3c99XETLli117C69QMlz31fmGLGRI0daacuWLUv6fJ07d046D0qfMmXK6PiFF16w0urWravjJ554wkq77bbbdDxv3ryox2USP02IiIjIe2wQERERkfcy3mVmTp12n3Rsdjm53Wlul1O2MFfmffTRR6OmPfzww1baKaecUrQFyzLLly+3tv/1r3/p2J2Wa3aTmVM308Es56xZs6w0c1rpjBkzrLQLLrigaAuWYeXLl9fx448/bqW529GY72/zqemAveqx+7NkN1nRcj+LzJWr3ZWkzW7Pq6++WseLFy+Omn+7du2s7QYNGhSqnJR5J598srX92GOP6bhWrVpWWt++fXVsdp8BJ3aLZwo/WYiIiMh7bBARERGR99ggIiIiIu9lfAyRuUz8/PnzrbSZM2fq2HyKLgC89tprRVuwQnr11Vd1bD59HQBuvfVWHQ8YMCBtZcoU96n1Zh/y+PHjrTRzXIj7SI54p9fv3r1bxwcOHLDSVqxYoeOFCxdaad9++62OJ02aZKVVqFBBxx07drTS3nvvPR3Xr18/rjLSceZT1F3mo2wqVaqUjuJQHEqVKmVtL1iwQMexxg2Z3M9yjgnLTTVr1sx0ERLG30QiIiLyHhtERERE5L2Md5mVLHm8CK1atbLSzC6zOXPmWGmvvPKKjq+//vqiKVwUn376qY7HjBljpZnTr2vUqGGlDR8+XMfmap+5yn1q/YQJE3TsTq2vXr26ji+//HIrzVwN1VwFWSll7ffxxx/rePv27VHLVbp0aWvbnNbtroj+xz/+UceNGjWKmiclbuLEiVHTzCnclD2OHj1qbZvTrGMxl2k444wzUlomSq/Dhw/r2B1+YH4fvvPOO1HzyNYhBrxDRERERN5jg4iIiIi8xwYREREReS/jY4hM5hR8APjuu+907D5l+e6779axOx6lZ8+eSZfFHCfkPrV+0KBBOt67d6+VdvHFF+vYfRKwO6Yo123cuDHufc26btGiRVzHuGOIzOMuuugiK81cKr5KlSpWWq4/ZqM4cpf9p+zw888/W9vmtPtYqlatqmN3/Ii5PIcPYytTbf/+/db2zp07dZyXl1eoPFevXq3jqVOnWmnjxo3Tsfm57apYsaK1PXbsWB3fdNNNhSpXUeMdIiIiIvIeG0RERETkvazqMnNXQR02bFjUfc0utDvvvDPqcQ0bNtSx+5Rlk/tk+l27dunY7RYzmatPA/bUet+6yFwPPfSQtW0+Gfubb76x0i655BIduyucmrfYY3Vvmbfly5Ytm1hhKS3Madvz5s2Lul/btm3TURxKk6+++krH7srjzZs317H7tAL3O4FO5H4Hffnllzo2v/9cbnfXhx9+qGNzpX9zmr3LHd5w7bXX6rhHjx5WWnFYuZp3iIiIiMh7bBARERGR99ggIiIiIu9l1Rgil/mIBXNsDgCcfvrpOh41apSVtmnTpojxtGnTop7LncJtTuXv1q2blfbEE0/ouHLlylYap40ed95551nb5qNYyE/mchbmuBJX3bp101EcygLt27fXMccMJa5BgwbW9uTJk3W8bNmyuPO58MILdWw+XsUdJ2RO5e/UqZOVdtJJxfseS/EuPREREVEKsEFERERE3svqLjOTeyv13nvv1XHr1q2tNPOWYbzcLjPzievuqse8rUtUOB999FGmi0BJcD/7zG5xc6p2hw4drP3MlYl3795tpZmr+1PihgwZEnOb4sc7REREROQ9NoiIiIjIe2wQERERkfeKzRiiWNzp3e42EWWHc889N+LrDz74oLVdsmROfDTlHHdZkZUrV2aoJESpxztERERE5D02iIiIiMh7vC9NRGnTpk0bHR87diyDJSEisvEOEREREXmPDSIiIiLyHhtERERE5D02iIiIiMh7bBARERGR99ggIiIiIu+J+5T3mDuL7ATwVdEVhwpQRylVPVWZsT4zLmX1ybrMOL43cwvfm7kj7rpMqEFERERElIvYZUZERETeY4OIiIiIvMcGEREREXmPDSIiIiLyHhtERERE5D02iIiIiMh7bBARERGR99ggIiIiIu+xQURERETe+/+Nwtw+BAaFFgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 720x864 with 10 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 定义比对可视化函数\n",
    "def plot_images_labels_prediction(images,  # 图像列表\n",
    "                                  labels,  # 标签列表\n",
    "                                  prediction,  # 预测值列表\n",
    "                                  index,  # 开始显示的索引\n",
    "                                  num=5):  # 缺省一次显示5张\n",
    "    fig = plt.gcf()  # 获取当前图表，get current figure\n",
    "    fig.set_size_inches(10, 12)  # 1英寸等于2.54cm\n",
    "\n",
    "    if num > 25:  # 最多显示25张图片\n",
    "        num = 25\n",
    "\n",
    "    for i in range(0, num):\n",
    "        ax = plt.subplot(5, 5, i + 1)  # 获取当前要处理的图片\n",
    "        ax.imshow(np.reshape(images[index], (28, 28)), cmap='binary')  # 显示第index个图像\n",
    "        title = 'label = ' + str(np.argmax(labels[index]))  # 显示标签的标题\n",
    "        if len(prediction) > 0:  # 如果有预测结果的话，添加显示预测的标题\n",
    "            title += ',predict = ' + str(prediction[index])\n",
    "        ax.set_title(title, fontsize=10)  # 显示图上的标题\n",
    "        # 不显示坐标轴\n",
    "        ax.set_xticks([])\n",
    "        ax.set_yticks([])\n",
    "        index += 1\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "# 可视化第300-309张测试图片的预测结果对比\n",
    "plot_images_labels_prediction(mnist.test.images,\n",
    "                              mnist.test.labels,\n",
    "                              prediction_result,\n",
    "                              300, 10)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
